﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using RoofRunner.GameComponents.Rendering;
using Microsoft.Xna.Framework;

namespace RoofRunner.Actors.ActorComponents.Rendering
{
    public class SkyComponent : ActorComponent
    {
        #region Fields
        private const int _numberOfVertices = 8;
        private const int _numberOfIndices = 36;
        private VertexBuffer _vertices = null;
        private IndexBuffer _indices = null;
        #endregion // Fields


        #region Properties
        public Effect SkyEffect { get; private set; }
        public TextureCube SkyTexture { get; set; }
        #endregion // Properties


        #region Methods
        public override void LoadContent(Microsoft.Xna.Framework.Content.ContentManager content)
        {
            SkyEffect = content.Load<Effect>("Sky\\SkyEffect");
            SkyTexture = content.Load<TextureCube>("Sky\\SkyBoxTex");

            SkyEffect.Parameters["tex"].SetValue(SkyTexture);
        }



        public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
        {

        }


        public override void Render(GameTime gameTime, RenderWorld renderWorld)
        {
            if (_vertices == null)
                CreateCubeVertexBuffer(renderWorld.Game.GraphicsDevice);
            if (_indices == null)
                CreateCubeIndexBuffer(renderWorld.Game.GraphicsDevice);

            renderWorld.Game.GraphicsDevice.SetVertexBuffer(_vertices);
            renderWorld.Game.GraphicsDevice.Indices = _indices;

            Matrix skyw = Matrix.CreateTranslation(renderWorld.Camera.Position);
            SkyEffect.Parameters["WVP"].SetValue(skyw * renderWorld.Camera.View * renderWorld.Camera.Projection);
            SkyEffect.CurrentTechnique.Passes[0].Apply();

            renderWorld.Game.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, _numberOfVertices, 0, _numberOfIndices / 3);

            base.Render(gameTime, renderWorld);
        }



        private void CreateCubeVertexBuffer(GraphicsDevice graphics)
        {
            Vector3[] cubeVertices = new Vector3[_numberOfVertices];

            cubeVertices[0] = new Vector3(-1, -1, -1);
            cubeVertices[1] = new Vector3(-1, -1, 1);
            cubeVertices[2] = new Vector3(1, -1, 1);
            cubeVertices[3] = new Vector3(1, -1, -1);
            cubeVertices[4] = new Vector3(-1, 1, -1);
            cubeVertices[5] = new Vector3(-1, 1, 1);
            cubeVertices[6] = new Vector3(1, 1, 1);
            cubeVertices[7] = new Vector3(1, 1, -1);

            VertexDeclaration VertexPositionDeclaration = new VertexDeclaration
                (
                    new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0)
                );

            _vertices = new VertexBuffer(graphics, VertexPositionDeclaration, _numberOfVertices, BufferUsage.WriteOnly);
            _vertices.SetData<Vector3>(cubeVertices);
        }

        void CreateCubeIndexBuffer(GraphicsDevice graphics)
        {
            UInt16[] cubeIndices = new UInt16[_numberOfIndices];

            //bottom face
            cubeIndices[0] = 0;
            cubeIndices[1] = 2;
            cubeIndices[2] = 3;
            cubeIndices[3] = 0;
            cubeIndices[4] = 1;
            cubeIndices[5] = 2;

            //top face
            cubeIndices[6] = 4;
            cubeIndices[7] = 6;
            cubeIndices[8] = 5;
            cubeIndices[9] = 4;
            cubeIndices[10] = 7;
            cubeIndices[11] = 6;

            //front face
            cubeIndices[12] = 5;
            cubeIndices[13] = 2;
            cubeIndices[14] = 1;
            cubeIndices[15] = 5;
            cubeIndices[16] = 6;
            cubeIndices[17] = 2;

            //back face
            cubeIndices[18] = 0;
            cubeIndices[19] = 7;
            cubeIndices[20] = 4;
            cubeIndices[21] = 0;
            cubeIndices[22] = 3;
            cubeIndices[23] = 7;

            //left face
            cubeIndices[24] = 0;
            cubeIndices[25] = 4;
            cubeIndices[26] = 1;
            cubeIndices[27] = 1;
            cubeIndices[28] = 4;
            cubeIndices[29] = 5;

            //right face
            cubeIndices[30] = 2;
            cubeIndices[31] = 6;
            cubeIndices[32] = 3;
            cubeIndices[33] = 3;
            cubeIndices[34] = 6;
            cubeIndices[35] = 7;

            _indices = new IndexBuffer(graphics, IndexElementSize.SixteenBits, _numberOfIndices, BufferUsage.WriteOnly);
            _indices.SetData<UInt16>(cubeIndices);

        }


        #endregion // Methods
    }
}
